package caip2022p.rcv6;

import java.util.*;
import java.io.*;

public class MainUseMap {
	//墙面高和宽
    static int N, M;
    //保存颜色分布
    static char[][] G;
    //记录是否贴了砖
    static int[][] vis;
    //自定义类，标记某个型号的砖（颜色和尺寸）
    static class Pair {
        char color;
        int size;

        Pair(char color, int size) {
            this.color = color;
            this.size = size;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Pair pair = (Pair) o;
            return color == pair.color && size == pair.size;
        }

        @Override
        public int hashCode() {
            return Objects.hash(color, size);
        }
    }
    //记录对应型号的砖的数量
    static Map<Pair, Integer> mp = new HashMap<>();
    
    //判断能否贴砖
    static boolean ok(int x, int y, char color) {
    	//(x,y)没超出墙面范围
    	//颜色符合要求
    	//(x,y)没有贴过
        return x >= 0 && x < N && y >= 0 && y < M && G[x][y] == color && vis[x][y] == 0;
    }

    //计算砖的尺寸
    static int f(char color, int x, int y) {
        int len = 1;
        while (true) {
            int flag = 0;
            for (int i = x; i < x + len; i++) {
                if (!ok(i, y + len - 1, color)) {
                    flag = 1;
                    break;
                }
            }
            if (flag == 0) {
                for (int i = y; i < y + len; i++) {
                    if (!ok(x + len - 1, i, color)) {
                        flag = 1;
                        break;
                    }
                }
            }
            if (flag == 1) break;
            len++;
        }
        len--;
        for (int i = x; i < x + len; i++) {
            for (int j = y; j < y + len; j++) {
                vis[i][j] = 1;
            }
        }
        return len;
    }

    public static void main(String[] args) throws IOException {
    	//优化输入
    	BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
    	//优化输出
        StringBuilder sb = new StringBuilder();
        
        String[] nm = br.readLine().split(" ");
        N = Integer.parseInt(nm[0]);
        M = Integer.parseInt(nm[1]);
        G = new char[N][M];
        vis = new int[N][M];

        //读取数据
        for (int i = 0; i < N; i++) {
            String line = br.readLine();
            for (int j = 0; j < M; j++) {
                G[i][j] = line.charAt(j);
            }
        }

        //循环墙面每个位置贴砖
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
                if (vis[i][j] == 1) continue;
                int size = f(G[i][j], i, j);
                Pair key = new Pair(G[i][j], size);
                mp.put(key, mp.getOrDefault(key, 0) + 1);
            }
        }

        //输出结果
        //System.out.println(mp.size());
        sb.append(mp.size());
        sb.append("\n");
        
        //排序
        List<Map.Entry<Pair, Integer>> sorted = new ArrayList<>(mp.entrySet());
        sorted.sort((a, b) -> {
            if (a.getKey().color != b.getKey().color) {
                return Character.compare(a.getKey().color, b.getKey().color);
            }
            return Integer.compare(a.getKey().size, b.getKey().size);
        });

        //输出结果
        for (Map.Entry<Pair, Integer> entry : sorted) {
        	sb.append(String.format("color = %c; size = %d; amount = %d%n", 
        			entry.getKey().color, entry.getKey().size, entry.getValue()));
//            System.out.printf("color = %c; size = %d; amount = %d%n",
//                    entry.getKey().color, entry.getKey().size, entry.getValue());
        }
        
        System.out.print(sb.toString());
    }
}